home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 13316 / 13316.xpi / content / treeViewCreator.js < prev    next >
Encoding:
JavaScript  |  2009-07-27  |  8.6 KB  |  273 lines

  1.  
  2. /* Copyright (C) 2009 Norman Solomon
  3.  * e-mail: historytree.addon@yahoo.com
  4.  * 
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the License.
  12.  */
  13.  
  14. // *******************************************************************************
  15. // *****                                                                     *****
  16. // *****      CREATES THE KEY DATA STRUCTURES USED BY THE EXTENSION          *****
  17. // *****   -----------------------------------------------------------       *****
  18. // *****   i.e. Creates gTreeNodes[] and gTabRoots[] using gNodeList[] and   *****
  19. // *****   gOpenTabIDs[] (passed via App storage from "firefoxOverlay.js")  *****
  20. // *****                                                                     *****
  21. // *******************************************************************************
  22.  
  23. // =====================================================================
  24. // Called when history is updated (see "historyViewer.js" onLoad() etc)
  25. // =====================================================================
  26. function buildFullHistoryTree()
  27. {
  28.     // Init all vars used in this function
  29.     var tabRoots = new Array();
  30.     var hNode;
  31.     var tNode, treeRoot, rootChild, tabRoot;
  32.     var FFtabID = "";
  33.     var rootTabID = "";
  34.     var added = false;
  35.     var rootNdx = 0;
  36.     var startNdx;
  37.     var prevSessNdx, sessNdx;
  38.  
  39.     // --------------------------------------------------------------
  40.     // Add a gTreeNodes[] sub-tree for every FF Tab in gNodeList[]
  41.     for (var i = 0; i < gNodeList.length; i++)
  42.     {
  43.         // Only process Tab root HistoryNode's
  44.         hNode = gNodeList[i];
  45.         if (hNode.sessHistNdx === 0)
  46.         {
  47.             // Add Tab root TreeNode to end of gTreeNodes[]
  48.             tNode = new TreeNode(null, null, null, BOX_WIDTH, BOX_HEIGHT + 18);
  49.             gTreeNodes.push(tNode);
  50.  
  51.             // Make HistoryNode point to its associated TreeNode
  52.             hNode.treeNodeNdx = gTreeNodes.length - 1;
  53.  
  54.             // Make TreeNode refer to its associated HistoryNode
  55.             tNode.histNode = hNode;
  56.             
  57.             // Set TreeNode Tab isOpenTab prop *** ONLY set for Tab Roots
  58.             tNode.inOpenTab = isOpenTab(hNode.tab);
  59.             
  60.             // Add Tab root to private array (added to gTabRoots[] below)
  61.             tabRoots.push(tNode);
  62.  
  63.             // Add Tab sub-tree - excluding the root
  64.             buildTabSubTreeForNdx(i);
  65.         }
  66.     }
  67.  
  68.     // --------------------------------------------------------------
  69.     // Add open Tab Root nodes to gTabRoots[] in same order as in FF
  70.     // (needed because user can drag and drop FF Tabs into any order)
  71.     for (var i = 0; i < gOpenTabIDs.length; i++)
  72.     {
  73.         // Get tabID for Tab currently open in FF
  74.         FFtabID = gOpenTabIDs[i];
  75.         added = false;
  76.         rootNdx = 0;
  77.  
  78.         // Add a TreeNode root for this open Tab to gTabRoots[]
  79.         while (!added && rootNdx < tabRoots.length)
  80.         {
  81.             tabRoot = tabRoots[rootNdx];
  82.             if (tabRoot.histNode.tab === FFtabID)
  83.             {
  84.                 added = true;
  85.                 gTabRoots.push(tabRoot);
  86.             }
  87.             else
  88.             {
  89.                 rootNdx ++;
  90.             }
  91.         }
  92.     }
  93.     
  94.     // Add closed Tab roots to gTabRoots[] - in the order user opened them
  95.     // These Tabs are NOT available to the user via the FF sessionHistory
  96.     for (var i = 0; i < tabRoots.length; i++)
  97.     {
  98.         tabRoot = tabRoots[i];
  99.         if (!tabRoot.inOpenTab)
  100.             gTabRoots.push(tabRoot);
  101.     }
  102.  
  103.     // -----------------------------------------------------------------
  104.     // Mark TreeNodes that have corresponding open pages in FF, enabling
  105.     // use of different color schemes for drawing closed or open TreeNodes
  106.     startNdx = gNodeList.length - 1;
  107.     for (var i = 0; i < gTabRoots.length; i++)
  108.     {
  109.         tabRoot = gTabRoots[i];
  110.         if (tabRoot.inOpenTab)
  111.         {
  112.             // Get tabID for Tab currently open in FF
  113.             rootTabID = tabRoot.histNode.tab;
  114.             prevSessNdx = null;
  115.  
  116.             // Loop backwards marking each currently open FF web-page
  117.             for (var ndx = startNdx; ndx >= 0; ndx--)
  118.             {
  119.                 hNode = gNodeList[ndx];
  120.                 sessNdx = hNode.sessHistNdx;
  121.                 if ((sessNdx < prevSessNdx || prevSessNdx === null) 
  122.                   && hNode.tab === rootTabID)
  123.                 {
  124.                     tNode = gTreeNodes[hNode.treeNodeNdx];
  125.                     tNode.isOpenPage = true;  // *** SET TreeNode prop
  126.                     prevSessNdx = sessNdx;
  127.                 }
  128.             }
  129.         }
  130.     }    
  131.  
  132.     // --------------------------------------------------------------
  133.     // MUST add dummy root node as FIRST element in gTreeNodes[]
  134.     treeRoot = new TreeNode(null, null, null, BOX_WIDTH, BOX_HEIGHT);
  135.     gTreeNodes.splice(0, 0, treeRoot);
  136.     
  137.     // Set the dummy root node's first child
  138.     rootChild = gTabRoots[0];
  139.     rootChild.parent = treeRoot;
  140.     treeRoot.child = rootChild;
  141.  
  142.     // Set the dummy root node's siblings (if any)
  143.     for (var i = 1; i < gTabRoots.length; i++)
  144.     {
  145.         tabRoot = gTabRoots[i];
  146.         tabRoot.parent = treeRoot;
  147.         rootChild.sibling = tabRoot;
  148.         rootChild = tabRoot;
  149.     }
  150.  
  151.     // ----------------------------------------------------------------
  152.     // Copy all TreeNode pointers - Enables restoration of current tree
  153.     for (var i = 0; i < gTreeNodes.length; i++)
  154.     {
  155.         tNode = gTreeNodes[i];
  156.         tNode.parentBak = tNode.parent;
  157.         tNode.childBak = tNode.child;
  158.         tNode.siblingBak = tNode.sibling;
  159.     }
  160. }
  161.  
  162. // ==========================================================
  163. // Adds a Tab sub-tree - Called from buildFullHistoryTree()
  164. // ==========================================================
  165. function buildTabSubTreeForNdx(histNdx)
  166. {
  167.     // Init vars needed to build tree
  168.     var hNode = gNodeList[histNdx];
  169.     var tabID = hNode.tab;
  170.     var tNode, tpNode, cNode;
  171.     var pHistNode;
  172.     var startNdx = histNdx + 1;
  173.  
  174.     // ---------------------------------------------------
  175.     // Add a matching TreeNode for every HistoryNode
  176.     for (var i = startNdx; i < gNodeList.length; i++)
  177.     {
  178.         // Only process non Tab root HistoryNode's for this Tab 
  179.         hNode = gNodeList[i];
  180.         if (hNode.tab === tabID && hNode.sessHistNdx > 0)
  181.         {
  182.             // Add a new TreeNode to end of gTreeNodes[]
  183.             tNode = new TreeNode(null, null, null, BOX_WIDTH, BOX_HEIGHT);
  184.             gTreeNodes.push(tNode);
  185.  
  186.             // Make HistoryNode point to its associated TreeNode
  187.             hNode.treeNodeNdx = gTreeNodes.length - 1;
  188.  
  189.             // Make TreeNode refer to its associated HistoryNode
  190.             tNode.histNode = hNode;
  191.         }
  192.     }
  193.  
  194.     // ---------------------------------------------------
  195.     // Set the parent, child and sibling pointer references
  196.     for (var i = startNdx; i < gNodeList.length; i++)
  197.     {
  198.         // Only process non Tab root HistoryNode's for this Tab 
  199.         hNode = gNodeList[i];
  200.         if (hNode.tab === tabID && hNode.sessHistNdx > 0)
  201.         {
  202.             // Get array index for parent 
  203.             pHistNode = parentHistNodeFromSessHistNdx
  204.                 (hNode.sessHistNdx - 1, i, tabID);
  205.             
  206.             // If parent was found set pointer references
  207.             if (pHistNode !== null)
  208.             {
  209.                 // Get child and parent TreeNode's using hNode pointers
  210.                 tNode = gTreeNodes[hNode.treeNodeNdx];
  211.                 tpNode = gTreeNodes[pHistNode.treeNodeNdx];
  212.  
  213.                 // Make this child point to its parent
  214.                 tNode.parent = tpNode;
  215.  
  216.                 // Set child OR sibling pointer
  217.                 if (tpNode.child === null)
  218.                 {
  219.                     // Make parent point to first child
  220.                     tpNode.child = tNode;
  221.                 }
  222.                 else
  223.                 {
  224.                     // Get last sibling in parents chain
  225.                     cNode = tpNode.child;
  226.                     while (cNode.sibling != null)
  227.                         cNode = cNode.sibling;
  228.  
  229.                     // Set last child's sibling = this child
  230.                     cNode.sibling = tNode;
  231.                 }
  232.             }
  233.         }
  234.     }
  235. }
  236.  
  237. // =========================================================
  238. // Returns req parent HistoryNode or null if its not found
  239. // =========================================================
  240. function parentHistNodeFromSessHistNdx(parentNdx, startNdx, tabID) 
  241. {
  242.     // Search backwards for parent with matching node.sessHistNdx
  243.     var node;
  244.     for (var i = startNdx; i >= 0; i--)
  245.     {
  246.         // Return HistoryNode if parent found
  247.         node = gNodeList[i];
  248.         if (node.sessHistNdx === parentNdx && node.tab === tabID)
  249.             return node;
  250.     }
  251.     
  252.     // Parent NOT found - So return null
  253.     return null;
  254. }
  255.  
  256. // ============================================================
  257. // Returns true if passed HistoryNode.tab is in an open FF tab
  258. // ============================================================
  259. function isOpenTab(tabID)
  260. {
  261.     // Loop down global list of open FF tabID's
  262.     var FFtabID;
  263.     for (var i = 0; i < gOpenTabIDs.length; i++)
  264.     {
  265.         // Return true if passed tabID matches
  266.         FFtabID = gOpenTabIDs[i];
  267.         if (tabID === FFtabID)
  268.             return true;
  269.     }
  270.  
  271.     // Passed HistoryNode.tab is in a closed FF Tab
  272.     return false;
  273. }